Skip to content

Conversation

@FrederikBolding
Copy link
Member

@FrederikBolding FrederikBolding commented Dec 1, 2025

Adds support for using the multichain API in Snaps. This is accomplished by setting up a separate provider and substream called metamask-multichain-provider. When snap.request is called with a multichain request, this provider and substream is used. The clients will need to route to the proper JSON-RPC pipeline based on the substream and verify that the Snap has the proper permission.

Additionally this PR adds a example Snap for usage of this API, that can leverage Ethereum and Solana APIs at once. It also adds limited simulation support for the multichain API. The simulation framework implements a basic version of the multichain API where sessions are tracked and requests are routed to supported EVM providers. There are no underlying providers for non-EVM request, but they can be mocked.

Breaking: This PR changes the default accounts used in snaps-jest to match the accounts derived from the default SRP.

Note: TBD if we hold off merging this until some bugs are squashed on extension that prevent non-EVM multichain API requests


Note

Adds first-class Multichain API support across runtime, RPC, SDK, simulation, and examples.

  • Execution environments: Route snap.request multichain calls via new metamask-multichain-provider substream; add isMultichainRequest and stream wiring in BaseSnapExecutor.
  • Permissions & endowments: Add endowment:multichain-provider and register builder; expose in permissions listing/tests.
  • SDK types: Add wallet_createSession, wallet_getSession, wallet_invokeMethod, wallet_revokeSession request/response types.
  • Simulation: New multichain middleware with session handling (create/get/revoke) and scoped wallet_invokeMethod routing; provider now respects CAIP-2 scope (EVM) and ignores non‑EVM; integrates CAIP‑25 caveat validation and simulated accounts; updates tests and defaults.
  • Examples & test app: New @metamask/multichain-provider-example-snap (EVM + Solana) with E2E tests; added UI in test-snaps to create/revoke sessions, switch chains, and sign.
  • Breaking: Default accounts updated to match default SRP (affects snaps-jest expectations).
  • Minor: coverage thresholds adjusted; yarn dependencies updated.

Written by Cursor Bugbot for commit 17795ea. This will update automatically on new commits. Configure here.

@socket-security
Copy link

socket-security bot commented Dec 1, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​metamask/​chain-agnostic-permission@​1.4.01001007895100

View full report

@FrederikBolding FrederikBolding force-pushed the fb/multichain-api branch 2 times, most recently from 917fc58 to 491f06d Compare January 7, 2026 10:58
@FrederikBolding FrederikBolding changed the title wip: Add Multichain API support feat: Add Multichain API support Jan 12, 2026
@codecov
Copy link

codecov bot commented Jan 13, 2026

Codecov Report

❌ Patch coverage is 98.93617% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 98.34%. Comparing base (b522af5) to head (17795ea).

Files with missing lines Patch % Lines
...s/snaps-execution-environments/src/common/utils.ts 33.33% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main    #3759    +/-   ##
========================================
  Coverage   98.33%   98.34%            
========================================
  Files         422      430     +8     
  Lines       12082    12250   +168     
  Branches     1876     1904    +28     
========================================
+ Hits        11881    12047   +166     
- Misses        201      203     +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

export const DEFAULT_ACCOUNTS: SimulationAccount[] = [
{
address: '0x1234567890abcdef1234567890abcdef12345678',
address: '0xc6d5a3c98ec9073b54fa0969957bd582e8d874bf',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this may be breaking, but it makes a lot more sense for this to return the address of the default account in the simulation IMO

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this should be considered breaking.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added note to the description

@FrederikBolding FrederikBolding marked this pull request as ready for review January 16, 2026 14:52
@FrederikBolding FrederikBolding requested a review from a team as a code owner January 16, 2026 14:52
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

@FrederikBolding FrederikBolding changed the title feat: Add Multichain API support feat!: Add Multichain API support Jan 19, 2026
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

case 'signTypedData': {
const params = request.params as SignTypedDataParams;
const accounts = await getAccounts(scope);
return await scopeModule.signTypedData(accounts[0], params.message);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Undefined account passed when accounts array is empty

Low Severity

The signMessage and signTypedData handlers use accounts[0] without checking if the array from getAccounts(scope) is empty. Since getAccounts returns session.sessionScopes[scope]?.accounts ?? [] (an empty array when no accounts exist), accounts[0] will be undefined when no session exists or the scope has no accounts. This undefined value gets passed to parseCaipAccountId() in the module methods, which will throw a confusing parsing error rather than a clear "no accounts available" message.

Fix in Cursor Fix in Web

case 'signTypedData': {
const params = request.params as SignTypedDataParams;
const accounts = await getAccounts(scope);
return await scopeModule.signTypedData(accounts[0], params.message);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing params validation causes crash on undefined access

Low Severity

The signMessage and signTypedData handlers cast request.params to SignMessageParams/SignTypedDataParams without validating that params exists. If a caller invokes these methods without providing params (valid in JSON-RPC), params will be undefined and accessing params.message will throw a TypeError: Cannot read properties of undefined. This is distinct from the previously reported empty accounts issue—here the crash occurs when no request params are provided at all.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants